import { BrowserWindow, BrowserWindowConstructorOptions } from 'electron'
import path from 'path'

export enum Status {
  used = 0,
  noUse = 1
}

class WindowPool {
  windows: { status: Status; win: BrowserWindow }[] = []

  constructor(private poolCount: number = 2) {
    this.initWindow(this.poolCount)
  }

  private initWindow(count: number): void {
    for (let i = 0; i < count; i++) {
      const win = new BrowserWindow({
        show: false,
        width: 600,
        height: 600,
        webPreferences: {
          sandbox: true,
          preload: path.join(__dirname, '../preload/index.js')
        }
      })

      this.windows.push({
        status: Status.noUse,
        win
      })
    }
  }

  private addCloseEvent(win: BrowserWindow): void {
    win.on('closed', () => {
      const index = this.windows.findIndex((t) => t.win === win)

      this.windows.splice(index, 1)
      this.checkPool()
    })
  }

  private setWinOptions(win: BrowserWindow, options: BrowserWindowConstructorOptions): void {
    const [width, height] = win.getSize()
    win.setSize(options.width ?? width, options.height ?? height)
    // 调用loadUrl加载的页面标题将会覆盖之前设置的标题
    win.setTitle(options.title ?? win.getTitle())
  }

  getSize(): number {
    return this.windows.length
  }

  checkPool(): void {
    const unUseTotal = this.windows.reduce((total, acc) => {
      if (acc.status === Status.noUse) {
        total += 1
      }
      return total
    }, 0)

    if (unUseTotal === 0) {
      this.initWindow(1)
    }
  }

  getWindow(options: BrowserWindowConstructorOptions): BrowserWindow {
    const window = this.windows.find((t) => t.status == Status.noUse)

    let win: BrowserWindow

    if (window) {
      window.status = Status.used
      win = window.win
      this.setWinOptions(win, options)
    } else {
      win = new BrowserWindow({ ...options, show: false })
      this.windows.push({
        win,
        status: Status.used
      })
    }

    this.checkPool()
    this.addCloseEvent(win)

    return win
  }
}

export { WindowPool }
